package uy.edu.ort.negocio;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import javax.ejb.ActivationConfigProperty;
import javax.ejb.EJB;
import javax.ejb.MessageDriven;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.TextMessage;
import org.apache.log4j.Logger;
import org.codehaus.jackson.JsonParseException;
import org.codehaus.jackson.map.JsonMappingException;
import org.codehaus.jackson.map.ObjectMapper;
import uy.edu.ort.dp.dominio.Fuente;
import uy.edu.ort.dominio.Noticia;
import uy.edu.ort.dp.interfaces.FuenteSBRemote;

/**
 *
 * @author Leo
 */
@MessageDriven(mappedName = "jms/ValidationQueue", activationConfig = {
    @ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue = "Auto-acknowledge"),
    @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue")
})
public class ValidarNoticiaMDB implements MessageListener {

    @EJB
    EncoladorObjetosSBLocal encolar;
    @EJB
    FuenteSBRemote ejbFuente;
    String cola = "jms/PublicationQueue";
    static Logger logger = Logger.getLogger(ValidarNoticiaMDB.class);

    public ValidarNoticiaMDB() {
    }

    @Override
    public void onMessage(Message message) {
        if (message != null) {
            // Valido que el mensaje obtenido sea del tipo esperado
            if (message instanceof TextMessage) {
                TextMessage m = (TextMessage) message;
                try {
                    Noticia noticia = validarNoticia(m.getText());
                    if (noticia != null) {
                        encolar.encolarNoticia(cola, noticia);
                    }
                } catch (JMSException ex) {
                    logger.error(ex.getMessage());
                }
            }
        }
    }

    private Noticia validarNoticia(String noticia) {
        String ret;
        ObjectMapper mapper = new ObjectMapper();
        Noticia jNoticia;
        try {
            jNoticia = mapper.readValue(noticia, Noticia.class);

            if (!validarFuente(jNoticia.getFuenteId(), jNoticia.getCodigoAutorizacion())) {
                ret = "Fuente id o código de autorización no validos.";
                logger.error(ret);              
                jNoticia = null;
            } else if (!existeTopico(jNoticia.getTopico())) {
                ret = "Topico " + jNoticia.getTopico() + " no válido.";
                logger.error(ret);
                jNoticia = null;
            } else {
                ret = "Se validó la noticia con exito: "
                        + " \n Título: " + jNoticia.getTitulo()
                        + " \n Contenido: " + jNoticia.getContenido()
                        + " \n Tópico: " + jNoticia.getTopico();
                logger.info(ret);
            }
        } catch (FileNotFoundException ex) {
            logger.error("No se encontró el archivo: " + ex.getMessage());
            jNoticia = null;
        } catch (JsonParseException ex) {
            logger.error("Format incorrecto de Noticia: " + ex.getMessage());
            jNoticia = null;
        } catch (JsonMappingException ex) {
            logger.error("No se puede mapear la entrada: " + ex.getMessage());
            jNoticia = null;
        } catch (IOException ex) {
            logger.error("Error desconocido: " + ex.getMessage());
            jNoticia = null;
        }
        return jNoticia;
    }

    private boolean existeTopico(String topico) throws FileNotFoundException, IOException {

        boolean ret = false;
        BufferedReader br = new BufferedReader(new FileReader("c:/agencia noticias/Topicos.txt"));
        String line = br.readLine();
        String[] topicos = line.split(",");

        Collection<String> listaTopicos = new ArrayList<String>();
        listaTopicos.addAll(Arrays.asList(topicos));

        for (String item : listaTopicos) {
            if (item.trim().equalsIgnoreCase(topico.trim())) {
                ret = true;
            }
        }
        return ret;

    }

    private boolean validarFuente(Long idFuente, String codigoAutorizacion) throws FileNotFoundException,
            NumberFormatException, IOException {
        boolean ret = true;

        Fuente dbFuente = ejbFuente.obtenerFuentePorId(idFuente);

        //No existe fuente
        if (dbFuente == null) {
            return false;
        } else if (!dbFuente.getCod_autorizacion().equals(codigoAutorizacion)) {
            return false;
        }

        return ret;
    }
}
